﻿/***************************************************************************
//* Foxit Software Inc.
//* Copyright(C) 2005-2012, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
//* and trade secrets of Foxit Software Inc.                                                      *
***************************************************************************/

/**
 * 工具函数
 */


define(function (require, exports, module) {
    var FXREADER = require('./FXReader.js');
    var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var base64DecodeChars = new Array(
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
        -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
    
    /**
     * @name FXREADER.Common
     * @namespace 
     * @description Common tools for JavaScript.
     */
    FXREADER.Common =
    {
    	/**
    	 * @description prevent event bubble.
    	 * @param {Object} event the event.
    	 * @param {Boolean} selection whether clear selection of the DOM.
    	*/    		
        PreventDefaults: function (e, selection) {
        	if (FXREADER.Environment.mobile || FXREADER.Environment.iOS)
                return;
            if (!e) {
                e = window.event;
            }
            if (e.preventDefault) {
                e.preventDefault();
            }
            try
            {
                if (selection && document.selection) {
                    document.selection.empty();
                }
            }
            catch(ex)
            {
            	
            }

        },
        GetHiddenParamValue: function(key)
        {
	        if (document.getElementById(key))
	            return document.getElementById(key).value;
	        else
	            return null;
        },
        QueryString: function (key) {

            return (document.location.search.match(new RegExp("(?:^\\?|&)" + key + "=(.*?)(?=&|$)")) || ['', null])[1];
        },
        
        /**
         * @description Insert a new html element after a element.
         * @param {Element} newElement new element to insert.
         * @param {Element} targetElement target element.
         * @return {Element} a reference to the new element.
         */
        insertAfter: function (newElement, targetElement) {
            var parent = targetElement.parentNode;
            var oElement = null;
            if (parent.lastChild == targetElement) {
                oElement = parent.appendChild(newElement);
            }
            else {
                oElement = parent.insertBefore(newElement, targetElement.nextSibling);
            }
            return oElement;
        },
        /**
         * @description convert timestamp to date.
         * @param {Object} nTimestamp timestamp.
         * @return {Date} the date of the timestamp.
         */
        Timestamp2Date: function (nTimestamp) {
            var d = new Date();
            var date = new Date((nTimestamp - d.getTimezoneOffset() * 60) * 1000); // 乘于1000是转为毫秒
            return date;
        },
        /**
         * @description UTC date to local date.
         * @param {Object} nTimestamp UTC timestamp.
         * @return {Date} local date.
         */
        Timestamp2DateString: function (nTimestamp, format) {
            var d = new Date();
            var date = new Date((nTimestamp - d.getTimezoneOffset() * 60) * 1000);
            return this.FormatDate(date, format);
        },
        AnnotTimeFormat: "M/d/yyyy hh:mm:ss",

        // 判断十六进制颜色是否偏黑，三分量相加的值是否超过255*3/2,如果超出返回false，表示偏白，否则返回true，表示偏黑
        // szColor的格式需为 #ffffff的形式
        IsColorBlack: function (szColor) {
            var szTmpColor = szColor.toLowerCase();
            if (szTmpColor) {
                // 处理六位的颜色值
                var sColorChange = [];
                var nTotalColor = 0;
                for (var i = 1; i < 7; i += 2) {
                    nTotalColor += parseInt("0x" + szTmpColor.slice(i, i + 2));
                }
                return nTotalColor * 2 < 255 * 3;
            } else {
                return true;
            }

            return true;
        },
        // html 文本转义
        htmlspecialchars: function (str) {
            str = str.replace(/&/g, '&amp;');
            str = str.replace(/</g, '&lt;');
            str = str.replace(/>/g, '&gt;');
            str = str.replace(/"/g, '&quot;');
            str = str.replace(/'/g, '&#039;');
            return str;
        },
        // html文本转义，支持更多字符
        htmlspecialchars_v2: function (str) {
            var s = "";
            if (str.length == 0) return "";
            for (var i = 0; i < str.length; i++) {
                switch (str.substr(i, 1)) {
                    case "<": s += "&lt;"; break;
                    case ">": s += "&gt;"; break;
                    case "&": s += "&amp;"; break;
                    case " ":
                        if (str.substr(i + 1, 1) == " ") {
                            s += " &nbsp;";
                            i++;
                        } else s += " ";
                        break;
                    case "\"": s += "&quot;"; break;
                    case "\n": s += "<br>"; break;
                    default: s += str.substr(i, 1); break;
                }
            }
            return s;
        },
        // 时间格式化
        FormatDate: function (date, format) {
            var o = {
                "M+": date.getMonth() + 1, // month
                "d+": date.getDate(), // day
                "h+": date.getHours(), // hour
                "m+": date.getMinutes(), // minute
                "s+": date.getSeconds(), // second
                "q+": Math.floor((date.getMonth() + 3) / 3), // quarter
                "S": date.getMilliseconds() // millisecond
            };

            if (/(y+)/.test(format)) {
                format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
            }

            for (var k in o) {
                if (new RegExp("(" + k + ")").test(format)) {
                    format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
                }
            }
            return format;
        },
        HexColor2Rgba: function (val, alpha) {
            var r, g, b;
            // 参数为RGB模式时不做进制转换，直接截取字符串即可
            if (/rgb/.test(val)) {
                var arr = val.match(/\d+/g);
                r = parseInt(arr[0]);
                g = parseInt(arr[1]);
                b = parseInt(arr[2]);
            }
            // 参数为十六进制时需要做进制转换
            else if (/#/.test(val)) {
                var len = val.length;
                // 非简写模式 #0066cc
                if (len === 7) {
                    r = parseInt(val.slice(1, 3), 16);
                    g = parseInt(val.slice(3, 5), 16);
                    b = parseInt(val.slice(5), 16);
                }
                // 简写模式 #06c
                else if (len === 4) {
                    r = parseInt(val.charAt(1) + val.charAt(1), 16);
                    g = parseInt(val.charAt(2) + val.charAt(2), 16);
                    b = parseInt(val.charAt(3) + val.charAt(3), 16);
                }
            }
            else {
                return val;
            }
            return "rgba(" + r + "," + g + "," + b + "," + alpha + ")";
        },
        /**
         * @description Update state of a button.
         * @param {String} btnId ID of the button.
         * @param {String} norClass  CSS styles of the button in normal state.
         * @param {String} disableClass CSS styles of the button in disable state .
         * @param {Boolean} bEnable whether to enable the button.
         */
        UpdateBtnState: function (btnId, norClass, disableClass, bEnable) {
            if (!bEnable) {
                $("#" + btnId).removeClass(norClass);
                $("#" + btnId).addClass(disableClass);
                $("#" + btnId).removeClass("fwr_toolbar_btn");
            }
            else {
                $("#" + btnId).removeClass(disableClass);
                $("#" + btnId).addClass(norClass);
                $("#" + btnId).addClass("fwr_toolbar_btn");
            }

        },
        ChangeUnit: function (fSrc, srcType, destType, nlog) {
            var fInch = 0.0;
            var UNIT_POINT = "point";
            var UNIT_INCH = "inch";
            var UNIT_CM = "cm";
            var UNIT_PICA = "pica";
            switch (srcType) {
                case UNIT_POINT:
                    fInch = fSrc / 72.0;
                    break;
                case UNIT_INCH:
                    fInch = fSrc;
                    break;
                case UNIT_CM:
                    fInch = fSrc / 2.54;
                    break;
                case UNIT_PICA:
                    fInch = fSrc / 6.0;
                    break;
                default:
                    break;
            }

            switch (destType) {
                case UNIT_POINT:
                    fInch *= 72.0;
                    break;
                case UNIT_INCH:
                    // fInch = fSrc;
                    break;
                case UNIT_CM:
                    fInch *= 2.54;
                    break;

                case UNIT_PICA:
                    fInch *= 6.0;
                    break;
                default:
                    break;
            }

            return fInch;
        },
        change2Decimal_f: function (x) {
            var f_x = parseFloat(x);
            if (x == NaN) {
                return false;
            }
            var f_x = Math.round(x * 100) / 100;
            var s_x = f_x.toString();
            var pos_decimal = s_x.indexOf('.');
            if (pos_decimal < 0) {
                pos_decimal = s_x.length;
                s_x += '.';
            }
            while (s_x.length <= pos_decimal + 2) {
                s_x += '0';
            }
            return s_x;
        },
        /*
		 * Clone Object.
		 */
        Clone: function (obj) {
            var clone;

            // Array.
            if (obj && (obj instanceof Array)) {
                clone = [];

                for (var i = 0; i < obj.length; i++)
                    clone[i] = this.Clone(obj[i]);

                return clone;
            }

            // "Static" types.
            if (obj === null
				|| (typeof (obj) != 'object')
				|| (obj instanceof String)
				|| (obj instanceof Number)
				|| (obj instanceof Boolean)
				|| (obj instanceof Date)
				|| (obj instanceof RegExp)) {
                return obj;
            }

            // Objects.
            clone = new obj.constructor();

            for (var propertyName in obj) {
                var property = obj[propertyName];
                clone[propertyName] = this.Clone(property);
            }

            return clone;
        },
        GetStringLength: function(str){
　　        var byteLen=0;var len=str.length;
　　        if(str){
　　　　        for(var i=0; i<len; i++){
　　　　　　        if(str.charCodeAt(i)>255){
　　　　　　　　        byteLen += 2;
　　　　　　      	   }
　　　　　　       	   else{
　　　　　　　　        byteLen++;
　　　　　　       	   }
　　　　        	 }
　　　　        return byteLen;
	　　        }
	　　        else{
	　　　　        return 0;
	　　   }
        },
       IsNeedRetry: function (state) {
            if (state==FXREADER.ConversionState.InProgress 
            		|| state==FXREADER.ConversionState.Initialize) {
                return true;
            }
            return false;
       },
       ContainsNode:function(parent, child, bContainSelf){
           if (!bContainSelf && parent === child) {
                return false;
            }
            if(parent.compareDocumentPosition){// w3c
                var res = parent.compareDocumentPosition(child);
                if(res === 20){
                    return true;
                }
            }else{
                if(parent.contains(child)){// ie
                    return true;
                }
            }
            return false;
        },
        /**
         * @description Base-64 encoder.
         * @param {String} the string to encode.
         */
        Base64encode : function(str)
        {
            var out, i, len;
            var c1, c2, c3;

            len = str.length;
            i = 0;
            out = "";
            while(i < len) {
	            c1 = str.charCodeAt(i++) & 0xff;
	            if(i == len)
	            {
	                out += base64EncodeChars.charAt(c1 >> 2);
	                out += base64EncodeChars.charAt((c1 & 0x3) << 4);
	                out += "==";
	                break;
	            }
	            c2 = str.charCodeAt(i++);
	            if(i == len)
	            {
	                out += base64EncodeChars.charAt(c1 >> 2);
	                out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
	                out += base64EncodeChars.charAt((c2 & 0xF) << 2);
	                out += "=";
	                break;
	            }
	            c3 = str.charCodeAt(i++);
	            out += base64EncodeChars.charAt(c1 >> 2);
	            out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
	            out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
	            out += base64EncodeChars.charAt(c3 & 0x3F);
            }
            return out;
        },
        /**
         * @description Base-64 decoder.
         * @param {String} the string to decode.
         */
		Base64decode : function(str)
		{
			 var c1, c2, c3, c4;
			    var i, len, out;

			    len = str.length;
			    i = 0;
			    out = "";
			    while(i < len) {
			    /* c1 */
			    do {
			        c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
			    } while(i < len && c1 == -1);
			    if(c1 == -1)
			        break;

			    /* c2 */
			    do {
			        c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
			    } while(i < len && c2 == -1);
			    if(c2 == -1)
			        break;

			    out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

			    /* c3 */
			    do {
			        c3 = str.charCodeAt(i++) & 0xff;
			        if(c3 == 61)
			        return out;
			        c3 = base64DecodeChars[c3];
			    } while(i < len && c3 == -1);
			    if(c3 == -1)
			        break;

			    out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

			    /* c4 */
			    do {
			        c4 = str.charCodeAt(i++) & 0xff;
			        if(c4 == 61)
			        return out;
			        c4 = base64DecodeChars[c4];
			    } while(i < len && c4 == -1);
			    if(c4 == -1)
			        break;
			    out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
			    }
			    return out;
		}
    }

    return FXREADER.Common;

});
